package JVM.old;

/**
 *   GC算法
 *  8.heap-->对象的生命周期---》OOM(java.lang.OutOfMemoryError) 内存不足错误
 *     更改java的虚拟机默认最大内存 -Xms1024m -Xmx1024m -XX:+PrintGCDetails
 *     -Xmn：新生区
 *     GC算法：
 *           1.引用计数法
 *                  //不咋用  缺点 每次赋值都要引用计数起麻烦    无法循环
 *           2.复制算法（Copying）
 *                  //常用算法   是年轻代用的垃圾回收算法    优点：不会产生内存碎片    缺点：费空间
 *           3.标记清除（Mark-Sweep）
 *                  //用在老年代    优点：节约空间    缺点：产生内存碎片  扫描2次  耗时长
 *           4.标记压缩（标记整理）（Mark-Compact）
 *                  //  老年代（多次清除时在压缩）  缺点：耗时最长（标记清除+整理）
 */

public class GC4种算法 {
    Object instance = null;
    public static void main(String[] args) {//所有线程的入口

        /**
         * 内存效率:
         *      复制算法>标记清除算法>标记整理算法(此处的效率只是简单的对比时间复杂度，实际情况不一定如此)。
         * 内存整齐度:
         *      复制算法=标记整理算法>标记清除算法。
         * 内存利用率:
         *      标记整理算法=标记清除算法>复制算法。
         *
         * 可以看出，效率上来说，复制算法是当之无愧的老大，但是却浪费了太多内存，而为了尽量兼顾上面所提到的三个指标，
         * 标记/整理算法相对来说更平滑--些，
         * 但效率上依然不尽如人意，它比复制算法多了一个标记的阶段，又比标记/清除多了一个整理内存的过程
         *
         * 难道就没有一种最优算法吗?G1垃圾回收
         *
         *
         */

    }

    private static void 标记压缩() {
        /**
         *标记/整理算法唯--的缺点就是效率也不高，
         * 不仅要标记所有存活对象，还要整理所有存活对象的引用地址。
         * 从效率.上来说，标记/整理算法要低于复制算法。
         *
         */
    }

    private static void 标记清除() {
        /**
         * 1、首先，它的缺点就是效率比较低(递归于全堆对象遍历)，
         *      而且在进行GC的时候，需要停止应用程序，这会导致用户体验非常差劲
         * 2、其次，主要的缺点则是这种方式清理出来的空闲内存是不连续的，
         *    这点不难理解，我们的死亡对象都是随即地出现在内存的各个角落的，
         *    现在把它们清除之后，内存的布局自然会乱七八糟。
         *    而为了应付这-- 点，JVM就不得不维持一个内存的空闲列表，
         *    这又是一种开销。而且在分配数组对象的时候，寻找连续的内存空间会不太好找。
         */
    }

    private static void 复制算法() {
        /**
         * 复制算法它的缺点也是相当明显的。
         * 1、它浪费了一半的内存，这太要命了。
         * 2、如果对象的存活率很高，我们可以极端一点，假设是100%存活，
         * 那么我们需要将所有对象都复制一遍，并将所有引用地址重置一遍。
         * 复制这一工作所花费的时间，在对象存活率达到一定程度时，将会变的不可忽视。
         * 所以从以上描述不难看出，复制算法要想使用，最起码对象的存活率要非常低才行，
         * 而且最重要的是，我们必须要克服50%内存的浪费。
         */
    }

    private static void 引用计数法() {
        GC4种算法 obj1 = new GC4种算法();
        GC4种算法 obj2 = new GC4种算法();
        obj1.instance=obj2;
        obj2.instance=obj1;
        obj1=null;obj2=null;

        //你指着我    我指着你   咋俩互相引用  循环引用   不会垃圾回收
        //所以引用计数法已经不常用了

        System.gc();//进行了一次gc   一般不要用
    }

}
